package com.elder.business.service.impl;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.elder.business.domain.*;
import com.elder.business.mapper.*;
import com.elder.common.core.page.TableDataInfo;
import com.elder.common.core.redis.RedisCache;
import com.elder.common.enums.BedType;
import com.elder.common.enums.RoomType;
import com.elder.common.utils.DateUtils;
import com.elder.common.utils.LongUtils;
import com.elder.common.utils.StringNewUtils;
import com.elder.common.utils.bean.BeanUtils;
import com.elder.common.utils.uuid.SnowGenerator;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.elder.business.service.IElderlyInfoService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 老人信息Service业务层处理
 * 
 * @author elder
 * @date 2023-11-26
 */
@Service
public class ElderlyInfoServiceImpl implements IElderlyInfoService 
{
    @Autowired
    private ElderlyInfoMapper elderlyInfoMapper;
    @Autowired
    private ElderFamiliesMapper elderFamiliesMapper;
    @Autowired
    private ApartmentRoomInfoMapper apartmentRoomInfoMapper;
    @Autowired
    private ElderlyApartmentBedsMapper elderlyApartmentBedsMapper;
    @Autowired
    private ElderlyapartmentMapper elderlyapartmentMapper;
    @Autowired
    private RetreatRecordsMapper retreatRecordsMapper;
    @Autowired
    private OrderInfoServiceImpl orderInfoService;
    @Autowired
    private ElderServiceMapper elderServiceMapper;
    @Autowired
    private RedisCache redisCache;

    private static final String ELDER_INFO_KEY = "allelderInfo";
    /**
     * 查询老人信息
     * 
     * @param elderId 老人信息主键
     * @return 老人信息
     */
    @Override
    public ElderlyInfoDTO selectElderlyInfoById(Long elderId)
    {
        ElderlyInfo elderlyInfo = elderlyInfoMapper.selectElderlyInfoById(elderId);
        ElderlyInfoDTO dto = new ElderlyInfoDTO();
        BeanUtils.copyProperties(elderlyInfo,dto);
        dto.setElderId(StringNewUtils.long2Str(elderlyInfo.getElderId()));
        dto.setBirthDate(DateUtils.dateStrMIAO(elderlyInfo.getBirthDate()));
        dto.setCheckInTime(DateUtils.dateStrMIAO(elderlyInfo.getCheckInTime()));
        dto.setCheckOutTime(DateUtils.dateStrMIAO(elderlyInfo.getCheckOutTime()));
        String[] str = new String[3];
        str[0]=StringNewUtils.long2Str(elderlyInfo.getApartmentId());
        str[1]=StringNewUtils.long2Str(elderlyInfo.getRoomId());
        str[2]=StringNewUtils.long2Str(elderlyInfo.getBedId());
        dto.setRoomTree(str);
        return dto;
    }

    /**
     * 查询老人信息列表
     *
     * @return 老人信息
     */
    @Override
    public TableDataInfo selectElderlyInfoList(String elderName, Integer pageNum,Integer pageSize)
    {
        //分页数据
        PageHelper.startPage(pageNum,pageSize);
        List<ElderlyInfo> list = elderlyInfoMapper.getElderList(elderName);
        PageInfo<ElderlyInfo> pageInfo = new PageInfo<>(list);
        List<ElderlyInfo> activitiesList = pageInfo.getList();
        //获取公寓
        Map<Long, String> apartMap = elderlyapartmentMapper.getAllApartmentInfo()
                .stream().collect(Collectors.toMap(Elderlyapartment::getApartmentId, Elderlyapartment::getApartmentName));
        List<Long> roomIds = activitiesList.stream().map(ElderlyInfo::getRoomId).collect(Collectors.toList());
        List<Long> bedIds = activitiesList.stream().map(ElderlyInfo::getBedId).collect(Collectors.toList());
        //获取公寓房间
        Map<Long,String> roomMap = new HashMap<>();
        Map<Long,String> bedMap = new HashMap<>();
        if(!CollectionUtils.isEmpty(roomIds)) {
            List<ApartmentRoomInfo> roomInfo = apartmentRoomInfoMapper.getApartmentRoomInfoByRoomIds(roomIds);
            roomMap = roomInfo.stream().collect(Collectors.toMap(ApartmentRoomInfo::getRoomId, ApartmentRoomInfo::getRoomCode));
        }
        if(!CollectionUtils.isEmpty(bedIds)) {
            List<ElderlyApartmentBeds> beds = elderlyApartmentBedsMapper.getBedsByBedIds(bedIds);
            bedMap = beds.stream().collect(Collectors.toMap(ElderlyApartmentBeds::getId, ElderlyApartmentBeds::getBedCode));
        }
        JSONObject obj = null;
        JSONArray result = new JSONArray();
        for(ElderlyInfo elder:activitiesList){
            obj = new JSONObject();
            obj.put("elderId", StringNewUtils.long2Str(elder.getElderId()));
            obj.put("elderName",elder.getElderName());
            obj.put("apartmentId",StringNewUtils.long2Str(elder.getApartmentId()));
            obj.put("apartmentName",Objects.isNull(apartMap.get(elder.getApartmentId()))?"":apartMap.get(elder.getApartmentId()));
            obj.put("elderImg",elder.getElderImg());
            obj.put("elderAge",elder.getElderAge());
            obj.put("elderGender",elder.getElderGender());
            obj.put("birthDate",StringNewUtils.long2Str(elder.getBirthDate()));
            obj.put("checkInTime",StringNewUtils.long2Str(elder.getCheckInTime()));
            obj.put("checkOutTime",StringNewUtils.long2Str(elder.getCheckOutTime()));
            obj.put("roomId",elder.getRoomId());
            obj.put("roomCode",Objects.isNull(roomMap.get(elder.getRoomId()))?"":roomMap.get(elder.getRoomId()));
            obj.put("bedCode",Objects.isNull(bedMap.get(elder.getBedId()))?"":bedMap.get(elder.getBedId()));
            obj.put("deposit",elder.getDeposit());
            obj.put("liveStatus",elder.getLiveStatus());
            obj.put("identityCardNumber",elder.getIdentityCardNumber());
            obj.put("contactPhone",elder.getContactPhone());
            obj.put("homeAddress",elder.getHomeAddress());
            obj.put("healthStatus",elder.getHealthStatus());
            obj.put("hasSurgeryHistory",elder.getHasSurgeryHistory());
            obj.put("hasChronicDisease",elder.getHasChronicDisease());
            obj.put("checkUserId",StringNewUtils.long2Str(elder.getCheckUserId()));
            obj.put("isUnusual",StringNewUtils.long2Str(elder.getIsUnusual()));
            obj.put("url",elder.getUrl());
            obj.put("notes",elder.getNotes());
            obj.put("checkUserName",elder.getCheckUserName());
            obj.put("drugName",elder.getDrugName());
            result.add(obj);
        }
        TableDataInfo data = new TableDataInfo();
        data.setCode(200);
        data.setMsg("success");
        data.setTotal(pageInfo.getTotal());
        data.setRows(result);
        return data;
    }

    /**
     * 新增老人信息
     * 
     * @param elderDTO 老人信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertElderlyInfo(ElderlyInfoDTO elderDTO)
    {
        ElderlyInfo elder = new ElderlyInfo();
        BeanUtils.copyProperties(elderDTO,elder);
        Long elderId = SnowGenerator.getId();
        elder.setElderId(elderId);
        Long longTime = DateUtils.getLongTime();
        List<String> roomlist = Arrays.asList(elderDTO.getRoomTree());
        elder.setApartmentId(LongUtils.str2Long(roomlist.get(0)));
        elder.setBirthDate(DateUtils.getTargetDateSeconds(elderDTO.getBirthDate()));
        elder.setCheckInTime(DateUtils.getDateSeconds(elderDTO.getCheckInTime()));
        elder.setCheckOutTime(DateUtils.getDateSeconds(elderDTO.getCheckOutTime()));
        elder.setCreateUserId(LongUtils.str2Long(elderDTO.getCreateUserId()));
        elder.setRoomId(LongUtils.str2Long(roomlist.get(1)));
        elder.setBedId(LongUtils.str2Long(roomlist.get(2)));
        elder.setCreateTime(longTime);
        elder.setIsEatMedication(StringNewUtils.isEmpty(elderDTO.getDrugName())?0:1);
        int age = DateUtils.getAgeFromIdCard(elderDTO.getIdentityCardNumber());
        elder.setElderAge(age);
        elderlyInfoMapper.insertElderlyInfo(elder);
        //老人入住 更新房间床位信息
        elderlyApartmentBedsMapper.updateElderlyApartmentBedInfo(elder.getRoomId(),elder.getBedId(),elder.getElderId());
        //根据roomId 获取room情况 是否满员
        List<ElderlyApartmentBeds> bedsList = elderlyApartmentBedsMapper.getElderRoomBedInfoByRoomId(elder.getRoomId());
        List<ElderlyApartmentBeds> beds = bedsList.stream().filter(rel -> Objects.equals(rel.getBedStatus(), BedType.BED_FREE.getValue())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(beds)){
            //满员 更新 房间入住情况
            apartmentRoomInfoMapper.updateApartmentRoomPeopleInfo(elder.getRoomId(), RoomType.ROOM_FULL.getValue());
        }
        //更新公寓入住人数
        elderlyapartmentMapper.updateElderlyapartmentLiveNum(elder.getApartmentId(),1);
        //删除缓存
        redisCache.deleteObject(ELDER_INFO_KEY);
        //生成订单；
        OrderInfoDTO order = new OrderInfoDTO();
        order.setOrderId(SnowGenerator.getId());
        order.setOrderTime(DateUtils.dateStrMIAO(DateUtils.getLongTime()));
        order.setLiveMonth(elderDTO.getLiveMonth());
        order.setElderId(elderId);
        order.setRoomId(elder.getRoomId());
        order.setRoomPriceId(elderDTO.getRoomPriceId());
        order.setRoomType(elderDTO.getRoomType());
        order.setLiveTime(elderDTO.getCheckInTime());
        order.setServiceIds(elderDTO.getProjectIds());
        order.setTotalAmount(elderDTO.getTotalAmount());
        order.setCustomerName(elderDTO.getElderName());
        order.setNotes(elderDTO.getOrderNotes());
        orderInfoService.addOrderInfo(order);
        return 1;
    }

    /**
     * 修改老人信息
     * 
     * @param elderDTO 老人信息
     * @return 结果
     */
    @Override
    public int updateElderlyInfo(ElderlyInfoDTO elderDTO)
    {
        ElderlyInfo elder = elderlyInfoMapper.getElderInfoByElderId(LongUtils.str2Long(elderDTO.getElderId()));
        BeanUtils.copyProperties(elderDTO,elder);
        elder.setElderId(LongUtils.str2Long(elderDTO.getElderId()));
        List<String> roomlist = Arrays.asList(elderDTO.getRoomTree());
        elder.setApartmentId(LongUtils.str2Long(roomlist.get(0)));
        elder.setCheckInTime(DateUtils.getDateSeconds(elderDTO.getCheckInTime()));
        elder.setCheckOutTime(DateUtils.getDateSeconds(elderDTO.getCheckOutTime()));
        elder.setUpdateUserId(LongUtils.str2Long(elderDTO.getUpdateUserId()));
        elder.setRoomId(LongUtils.str2Long(roomlist.get(1)));
        elder.setBedId(LongUtils.str2Long(roomlist.get(2)));
        elder.setUpdateTime(DateUtils.getLongTime());
        elderlyInfoMapper.updateElderlyInfo(elder);
        CompletableFuture.runAsync(() -> {
            ElderlyApartmentBeds elderBed = elderlyApartmentBedsMapper.getElderRoomBedInfoByElderId(elder.getElderId());
            //判断房间剩余数量
            List<ElderlyApartmentBeds> elderRoomInfo = elderlyApartmentBedsMapper.getElderRoomBedInfoByRoomId(elder.getRoomId());
            if(Objects.isNull(elderBed)){
                elderlyApartmentBedsMapper.setElderRoomBedInfo(BedType.getCnName(elder.getLiveStatus()),elder.getElderId(),elder.getBedId());
                //如果差一人住满，更新房间入住情况
                if(elderRoomInfo.size()==1){
                    apartmentRoomInfoMapper.updateApartmentRoomPeopleInfo(elder.getRoomId(), RoomType.ROOM_FULL.getValue());
                }
            }else {
                elderlyApartmentBedsMapper.updateElderlyApartmentBedInfo(elder.getRoomId(),elder.getBedId(),elder.getElderId());
            }
        });
        //删除缓存
        redisCache.deleteObject(ELDER_INFO_KEY);

        return 1;
    }

    /**
     * 批量删除老人信息
     * 
     * @param ids 需要删除的老人信息主键
     * @return 结果
     */
    @Override
    public int deleteElderlyInfoByIds(Long[] ids)
    {
        return elderlyInfoMapper.deleteElderlyInfoByIds(ids);
    }

    /**
     * 删除老人信息信息
     * 
     * @param id 老人信息主键
     * @return 结果
     */
    @Override
    public int deleteElderlyInfoById(Long id)
    {
        return elderlyInfoMapper.deleteElderlyInfoById(id);
    }

    @Override
    public List<ElderlyInfo> selectElderlyInfoExportList(ElderlyInfo elderlyInfo) {
        return elderlyInfoMapper.selectElderlyInfoList(elderlyInfo);
    }

    @Override
    public List<JSONObject> selectElderlyAllList() {
        List<JSONObject> cacheList = redisCache.getCacheList(ELDER_INFO_KEY);
        if(CollectionUtils.isNotEmpty(cacheList)){
            return cacheList;
        }
        List<ElderlyInfo> allElderList = elderlyInfoMapper.selectElderlyInfoList(new ElderlyInfo());
        JSONObject obj = null;
        List<JSONObject> result = new ArrayList<>();
        for(ElderlyInfo dto : allElderList){
            obj = new JSONObject();
            obj.put("elderId",StringNewUtils.long2Str(dto.getElderId()));
            obj.put("apartmentId",StringNewUtils.long2Str(dto.getApartmentId()));
            obj.put("apartmentName",dto.getApartmentName());
            obj.put("elderName",dto.getElderName());
            obj.put("elderGender",dto.getElderGender());
            result.add(obj);
        }
        if(CollectionUtils.isNotEmpty(result)) {
            redisCache.setCacheList(ELDER_INFO_KEY, result);
        }
        return result;
    }

    @Override
    public List<JSONObject> getElderlyFiles(String elderName) {
        ElderlyInfo elderlyInfo = new ElderlyInfo();
        elderlyInfo.setElderName(elderName);
        List<ElderlyInfo> list = elderlyInfoMapper.selectElderlyInfoList(elderlyInfo);
        List<Long> elderIds = list.stream().map(ElderlyInfo::getElderId).collect(Collectors.toList());
        List<ElderFamilies> familiesList = elderFamiliesMapper.getElderFamiliesByelderId(elderIds);
        Map<Long, List<ElderFamilies>> familiesMap = familiesList.stream().collect(Collectors.groupingBy(ElderFamilies::getElderId, Collectors.toList()));
        List<JSONObject> result = list.stream().map(v -> {
            JSONObject obj = new JSONObject();
            obj.put("elderId", StringNewUtils.long2Str(v.getElderId()));
            obj.put("elderName", v.getElderName());
            obj.put("apartmentId", StringNewUtils.long2Str(v.getApartmentId()));
            obj.put("apartmentName", v.getApartmentName());
            obj.put("elderImg", v.getElderImg());
            obj.put("elderAge", v.getElderAge());
            obj.put("elderGender", v.getElderGender());
            obj.put("birthDate", StringNewUtils.long2Str(v.getBirthDate()));
            obj.put("checkInTime", StringNewUtils.long2Str(v.getCheckInTime()));
            obj.put("checkOutTime", StringNewUtils.long2Str(v.getCheckOutTime()));
            obj.put("roomId", v.getRoomId());
            obj.put("bedCode", v.getBedCode());
            obj.put("deposit", v.getDeposit());
            obj.put("liveStatus", v.getLiveStatus());
            obj.put("identityCardNumber", v.getIdentityCardNumber());
            obj.put("contactPhone", v.getContactPhone());
            obj.put("homeAddress", v.getHomeAddress());
            obj.put("healthStatus", v.getHealthStatus());
            obj.put("hasSurgeryHistory", v.getHasSurgeryHistory());
            obj.put("hasChronicDisease", v.getHasChronicDisease());
            obj.put("notes", v.getNotes());
            obj.put("families", familiesMap.get(v.getElderId()));
            return obj;
        }).collect(Collectors.toList());
        return result;
    }

    /***
     * @description 获取今日入住老人信息
     * @return JSONObject
     * @author zyk
     * @date 2024/2/29 17:10
     */
    @Override
    public JSONObject getTodayJoinElderInfo() {
        Long longTime = DateUtils.getLongTime();
        Long startTime = DateUtils.getDayStartTime(longTime);
        Long endTime = DateUtils.getDayEndTime(longTime);
        List<ElderlyInfo> elderInfo = elderlyInfoMapper.getTodayJoinElderInfo(startTime, endTime);
        int mancount = 0;
        int womancount = 0;
        for(ElderlyInfo dto : elderInfo){
            if("男".equals(dto.getElderGender())){
                mancount++;
            }else{
                womancount++;
            }
        }
        List<RetreatRecords> retreatTodayCount = retreatRecordsMapper.getRetreatTodayCount(startTime, endTime);
        JSONObject obj = new JSONObject();
        obj.put("total",elderInfo.size());
        obj.put("mancount",mancount);
        obj.put("womancount",womancount);
        obj.put("backcount",retreatTodayCount.size());
        return obj;
    }

    @Override
    public JSONObject getElderInfoByName(String elderName) {
        JSONObject result = new JSONObject();
        if(StringNewUtils.isEmpty(elderName)){
            List<JSONObject> list = new ArrayList<>();
            result.put("code","200");
            result.put("data",list);
            return result;
        }
        List<ElderlyInfo> elderinfoList = elderlyInfoMapper.getElderinfoList(elderName);
        List<JSONObject> list = elderinfoList.stream().map(v -> {
            JSONObject obj = new JSONObject();
            obj.put("elderId", StringNewUtils.long2Str(v.getElderId()));
            obj.put("elderName", v.getElderName());
            obj.put("apartmentId", StringNewUtils.long2Str(v.getApartmentId()));
            obj.put("elderAge", v.getElderAge());
            obj.put("elderGender", v.getElderGender());
            obj.put("roomId", v.getRoomId());
            obj.put("bedCode", v.getBedCode());
            obj.put("deposit", v.getDeposit());
            obj.put("liveStatus", v.getLiveStatus());
            obj.put("identityCardNumber", v.getIdentityCardNumber());
            obj.put("contactPhone", StringNewUtils.formatStr(v.getContactPhone()));
            obj.put("homeAddress", StringNewUtils.formatStr(v.getHomeAddress()));
            return obj;
        }).collect(Collectors.toList());
        result.put("code","200");
        result.put("data",list);
        return result;
    }
}
